//! # 超时管理模块
//!
//! 提供统一的超时控制和管理功能

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use tokio::time::timeout;
use crate::ResilienceResult;

/// 超时配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimeoutConfig {
    /// 连接超时
    pub connect_timeout: Duration,
    /// 请求超时
    pub request_timeout: Duration,
    /// 空闲超时
    pub idle_timeout: Duration,
    /// 总体超时
    pub total_timeout: Option<Duration>,
    /// 是否启用超时
    pub enabled: bool,
}

/// 超时策略
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TimeoutStrategy {
    /// 固定超时
    Fixed { timeout: Duration },
    /// 自适应超时
    Adaptive { 
        min_timeout: Duration, 
        max_timeout: Duration,
        percentile: f64,
    },
    /// 自定义超时
    Custom { name: String },
}

/// 超时结果
#[derive(Debug)]
pub enum TimeoutResult<T> {
    /// 成功完成
    Success(T),
    /// 超时
    Timeout { elapsed: Duration },
    /// 错误
    Error(String),
}

/// 超时错误
#[derive(Debug, thiserror::Error)]
pub enum TimeoutError {
    #[error("操作超时: {operation}, 耗时: {elapsed:?}, 超时限制: {timeout:?}")]
    Elapsed {
        operation: String,
        elapsed: Duration,
        timeout: Duration,
    },
    #[error("超时配置错误: {0}")]
    ConfigError(String),
}

/// 超时管理器接口
#[async_trait]
pub trait TimeoutManager: Send + Sync {
    /// 执行带超时的操作
    async fn execute_with_timeout<F, T>(
        &self,
        operation: F,
        timeout_duration: Duration,
    ) -> TimeoutResult<T>
    where
        F: std::future::Future<Output = T> + Send,
        T: Send;
    
    /// 获取超时配置
    fn get_config(&self) -> &TimeoutConfig;
    
    /// 更新超时配置
    fn update_config(&mut self, config: TimeoutConfig);
    
    /// 获取超时统计
    async fn get_timeout_stats(&self) -> TimeoutStats;
}

/// 超时统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TimeoutStats {
    /// 总操作数
    pub total_operations: u64,
    /// 超时操作数
    pub timeout_operations: u64,
    /// 成功操作数
    pub success_operations: u64,
    /// 平均执行时间
    pub average_duration: Duration,
    /// 超时率
    pub timeout_rate: f64,
}

/// 默认超时管理器
pub struct DefaultTimeoutManager {
    config: TimeoutConfig,
    stats: TimeoutStats,
}

impl DefaultTimeoutManager {
    pub fn new(config: TimeoutConfig) -> Self {
        Self {
            config,
            stats: TimeoutStats::default(),
        }
    }
}

#[async_trait]
impl TimeoutManager for DefaultTimeoutManager {
    async fn execute_with_timeout<F, T>(
        &self,
        operation: F,
        timeout_duration: Duration,
    ) -> TimeoutResult<T>
    where
        F: std::future::Future<Output = T> + Send,
        T: Send,
    {
        let start = std::time::Instant::now();
        
        match timeout(timeout_duration, operation).await {
            Ok(result) => {
                let elapsed = start.elapsed();
                // TODO: 更新统计信息
                TimeoutResult::Success(result)
            }
            Err(_) => {
                let elapsed = start.elapsed();
                // TODO: 更新统计信息
                TimeoutResult::Timeout { elapsed }
            }
        }
    }
    
    fn get_config(&self) -> &TimeoutConfig {
        &self.config
    }
    
    fn update_config(&mut self, config: TimeoutConfig) {
        self.config = config;
    }
    
    async fn get_timeout_stats(&self) -> TimeoutStats {
        self.stats.clone()
    }
}

impl Default for TimeoutConfig {
    fn default() -> Self {
        Self {
            connect_timeout: Duration::from_secs(30),
            request_timeout: Duration::from_secs(60),
            idle_timeout: Duration::from_secs(300),
            total_timeout: Some(Duration::from_secs(300)),
            enabled: true,
        }
    }
}

impl Default for TimeoutStats {
    fn default() -> Self {
        Self {
            total_operations: 0,
            timeout_operations: 0,
            success_operations: 0,
            average_duration: Duration::from_millis(0),
            timeout_rate: 0.0,
        }
    }
}

/// 超时工具函数
pub mod utils {
    use super::*;
    
    /// 带超时的异步操作包装器
    pub async fn with_timeout<F, T>(
        future: F,
        timeout_duration: Duration,
    ) -> Result<T, TimeoutError>
    where
        F: std::future::Future<Output = T>,
    {
        match timeout(timeout_duration, future).await {
            Ok(result) => Ok(result),
            Err(_) => Err(TimeoutError::Elapsed {
                operation: "async operation".to_string(),
                elapsed: timeout_duration,
                timeout: timeout_duration,
            }),
        }
    }
    
    /// 计算自适应超时时间
    pub fn calculate_adaptive_timeout(
        response_times: &[Duration],
        percentile: f64,
        min_timeout: Duration,
        max_timeout: Duration,
    ) -> Duration {
        if response_times.is_empty() {
            return min_timeout;
        }
        
        let mut sorted_times = response_times.to_vec();
        sorted_times.sort();
        
        let index = ((sorted_times.len() - 1) as f64 * percentile) as usize;
        let timeout = sorted_times[index];
        
        timeout.clamp(min_timeout, max_timeout)
    }
}